using System;
using System.Diagnostics;
using System.Reflection;
using System.Windows.Forms;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
using TXLooker.WorkItemExtention.Core;

namespace TXLooker.WorkItemExtention.UI
{
    internal partial class WIQLForm : Form
    {
        protected WIServerProvider ServerProvider
        {
            get { return this.m_server; }
            private set
            {
                this.m_server = value;
            }
        }
        private WIServerProvider m_server = null;

        protected WIServerProvider ProjectProvider 
        {
            get { return this.m_project; }
            private set
            {
                this.m_project = value;
            }
        }
        private WIServerProvider m_project = null;

        protected WIQueriesRoot QueriesRoot
        {
            get { return this.m_queriesRoot; }
            private set
            {
                this.m_queriesRoot = value;
            }
        }
        private WIQueriesRoot m_queriesRoot = null;

        protected WIQueriesGroup QueriesGroup
        {
            get { return this.m_queriesGroup; }
            private set
            {
                this.m_queriesGroup = value;
            }
        }
        private WIQueriesGroup m_queriesGroup = null;

        public WIQLForm()
        {
            InitializeComponent();

            m_gridQueryResults.CellDoubleClick += new DataGridViewCellEventHandler( OnWorkItemCellDoubleClick );
            m_tfsTreeCtrl.SelectionChanged += new EventHandler(OnTreeSelectionChanged);
        }

        private void OnTreeSelectionChanged( object sender, EventArgs args )
        {
            WIObject selectedItem = this.m_tfsTreeCtrl.SelectedObject;

            switch( selectedItem.Type )
            {
                case WIObjectType.Server:
                    this.m_btnCreateQuery.Enabled = false;
                    this.m_btnUpdateQuery.Enabled = false;
                    break;
                case WIObjectType.Project:
                case WIObjectType.QueriesRoot:
                    this.m_btnCreateQuery.Enabled = true;
                    this.m_btnUpdateQuery.Enabled = false;
                    break;
                case WIObjectType.QueriesGroup:
                    {
                        this.m_btnCreateQuery.Enabled = true;
                        this.m_btnUpdateQuery.Enabled = false;

                        switch( (selectedItem as WIQueriesGroup).QueryScope )
                        {
                            case QueryScope.Public:
                                this.m_rbtnTeamQuery.Checked = true;
                                break;
                            case QueryScope.Private:
                                this.m_rbtnMyQuery.Checked = true;
                                break;
                        }
                    }
                    break;
                case WIObjectType.Query:
                    {
                        Cursor crsr = this.Cursor;

                        try
                        {
                            this.Cursor = Cursors.WaitCursor;

                            StoredQuery query = null;
                            
                            try
                            {
                                query = (selectedItem as WIStoredQuery).GetQuery();
                            }
                            catch( Exception ex )
                            {
                                MessageBox.Show( "Query can not be received from server." );
                                Debug.WriteLine( ex.ToString() );
                            }

                            if( query != null )
                            {
                                this.m_btnCreateQuery.Enabled = true;
                                this.m_btnUpdateQuery.Enabled = true;

                                this.m_tbQueryTitle.Text = query.Name;
                                this.m_tbQueryBody.Text = query.QueryText;

                                switch( query.QueryScope )
                                {
                                    case QueryScope.Public:
                                        this.m_rbtnTeamQuery.Checked = true;
                                        break;
                                    case QueryScope.Private:
                                        this.m_rbtnMyQuery.Checked = true;
                                        break;
                                }
                            }
                        }
                        finally
                        {
                            this.Cursor = crsr;
                        }
                    }
                    break;
                default:
                    throw new NotImplementedException();
            }
        }
        protected override void OnLoad( EventArgs e )
        {
            base.OnLoad(e);

            this.m_tfsTreeCtrl.LoadF();
        }

        private void OnCreateQuery( object sender, EventArgs e )
        {
            WIStoredQuery wiQuery = this.m_tfsTreeCtrl.SelectedObject as WIStoredQuery;
            if( wiQuery == null ) return;

            Project project = this.GetProject( wiQuery );

            if( project == null )
            {
                MessageBox.Show( string.Format( "Project '{0}' not found or server is not available", project.Name ) );
                return;
            }

            try
            {
                QueryScope qscope = this.m_rbtnTeamQuery.Checked ? QueryScope.Public : QueryScope.Private;
                project.StoredQueries.Add( new StoredQuery( qscope, m_tbQueryTitle.Text, this.m_tbQueryBody.Text, string.Empty ) );
            }
            catch( Exception ex )
            {
                MessageBox.Show( string.Format( "Error query creation: '{0}'", ex.ToString() ) );
            }

        }
        private void OnUpdateQuery( object sender, EventArgs e )
        {
            WIStoredQuery wiQuery = this.m_tfsTreeCtrl.SelectedObject as WIStoredQuery;
            if( wiQuery == null ) return;

            Cursor cursor = this.Cursor;

            try
            {
                this.Cursor = Cursors.WaitCursor;

                StoredQuery query = wiQuery.GetQuery();

                query.QueryScope = this.m_rbtnTeamQuery.Checked ? QueryScope.Public : QueryScope.Private;
                query.QueryText = this.m_tbQueryBody.Text;
                query.Name = this.m_tbQueryTitle.Text;

                query.Update();
            }
            catch( Exception ex )
            {
                MessageBox.Show( string.Format("Error query update: '{0}'", ex.Message ) );
            }
            finally
            {
                this.Cursor = cursor;
            }

        }
        private void OnExecQuery( object sender, EventArgs e )
        {
            WIObject wiObject = this.m_tfsTreeCtrl.SelectedObject;
            if( wiObject == null ) return;

            Cursor cur = this.Cursor;

            try
            {
                this.Cursor = Cursors.WaitCursor;

                Project project = this.GetProject( wiObject );

                if( project == null )
                {
                    MessageBox.Show( "Project not available." );
                    return;
                }

                string queryText = this.m_tbQueryBody.Text.Replace( "@project", string.Format( "'{0}'", project.Name ) );
                this.m_gridQueryResults.LoadFromWiql( project.Store, queryText );
            }
            catch( Exception ex )
            {
                MessageBox.Show( string.Format( "Error occured: '{0}'", ex.Message ) );
            }
            finally
            { 
                this.Cursor = cur;
            }

        }
        private void OnWorkItemCellDoubleClick( object sender, DataGridViewCellEventArgs e )
        {
            int[] IDs = this.m_gridQueryResults.GetSelectedIds();

            WorkItem workItem = this.m_gridQueryResults.WorkItemCollection.Store.GetWorkItem( IDs[0] );

            WorkItemForm form = new WorkItemForm( workItem );
            form.ShowDialog();
        }

        private Project GetProject( WIObject item )
        {
            Project project = null;

            WIObject wiObject = this.m_tfsTreeCtrl.SelectedObject;

            if( wiObject != null )
            {
                try
                {
                    switch( wiObject.Type )
                    {
                        case WIObjectType.Server:
                            break;
                        case WIObjectType.Project:
                            project = ( wiObject as WIProjectProvider ).GetProject();
                            break;
                        case WIObjectType.QueriesRoot:
                        case WIObjectType.QueriesGroup:
                        case WIObjectType.Query:
                            WIProjectProvider provider = (WIProjectProvider)wiObject.GetType().InvokeMember( "ProjectProvider", BindingFlags.GetProperty, null, wiObject, null );
                            project = provider.GetProject();
                            break;
                        default:
                            throw new NotImplementedException();
                    }
                }
                catch( Exception ex )
                {
                    Debug.WriteLine( ex.ToString() );
                }
            }

            return project;
        }
    }
}